/*
 * Copyright 2008 Zoundry LLC, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package org.zoundry.gaedt.ui.wizards;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.resource.ImageDescriptor;
import org.osgi.framework.Bundle;
import org.python.pydev.ui.wizards.project.IWizardNewProjectNameAndLocationPage;
import org.python.pydev.ui.wizards.project.PythonProjectWizard;
import org.zoundry.gaedt.core.ZGaeException;
import org.zoundry.gaedt.core.models.application.ZGaeApplicationModel;
import org.zoundry.gaedt.core.models.application.ZGaeHandlerModel;
import org.zoundry.gaedt.core.util.ZGaeCloser;
import org.zoundry.gaedt.core.util.ZGaeResourceUtil;
import org.zoundry.gaedt.core.util.ZGaeUtil;
import org.zoundry.gaedt.sdk.ZGaeSDKActivator;
import org.zoundry.gaedt.ui.ZGaeUIImages;
import org.zoundry.gaedt.ui.nature.ZGaeNatureUtil;


/**
 * Wizard used to create a Google App Engine project.
 */
public class ZGaeProjectWizard extends PythonProjectWizard
{
    public static final String GAE_WIZARD_ID = "org.zoundry.gaedt.ui.wizards.ZGaeProjectWizard";

    /** The project created by the wizard. */
    private IProject mProject;

    /**
     * C'tor.
     */
    public ZGaeProjectWizard()
    {
    }

    /**
     * @see org.python.pydev.ui.wizards.project.PythonProjectWizard#initializeDefaultPageImageDescriptor()
     */
    @Override
    protected void initializeDefaultPageImageDescriptor()
    {
        ImageDescriptor desc = ZGaeUIImages.getImageDescriptor("images/wizards/appengine_logo.jpg");
        setDefaultPageImageDescriptor(desc);
    }

    /**
     * @see org.python.pydev.ui.wizards.project.PythonProjectWizard#createProjectPage()
     */
    @Override
    protected IWizardNewProjectNameAndLocationPage createProjectPage()
    {
        return new ZGaeWizardNewProjectNameAndLocationPage();
    }

    /**
     * @see org.python.pydev.ui.wizards.project.PythonProjectWizard#performFinish()
     */
    @Override
    public boolean performFinish()
    {
        super.performFinish();

        ZGaeApplicationModel model = new ZGaeApplicationModel(getProject());
        try
        {
            ZGaeResourceUtil.openEditor(model.getAppYaml());
        }
        catch (ZGaeException e)
        {
            ZGaeUtil.logError(e);
        }

        return true;
    }

    /**
     * @see org.python.pydev.ui.wizards.project.PythonProjectWizard#addProjectReferencePage()
     */
    @Override
    protected void addProjectReferencePage()
    {
        // Override to do nothing - GAE projects can't have dependencies
    }

    /**
     * @see org.python.pydev.ui.wizards.project.PythonProjectWizard#createNewProject()
     */
    @Override
    protected IProject createNewProject()
    {
        IProject project = super.createNewProject();
        if (project != null)
        {
            ZGaeNatureUtil.addNature(project);
            createDefaultYaml(project);
        }
        setProject(project);
        return project;
    }

    /**
     * Creates default app.yaml, index.yaml, gae.yaml files in the new project.
     *
     * @param aProject
     */
    protected void createDefaultYaml(IProject aProject)
    {
        ZGaeApplicationModel model = new ZGaeApplicationModel(aProject);
        model.setName(aProject.getName().toLowerCase());
        model.setRuntimeType("python");
        model.setVersion(1);
        model.setApiVersion(1);
        model.setDevPort(8080);

        // Add a handler to the application model.
        ZGaeHandlerModel handler = new ZGaeHandlerModel();
        handler.setUrl(".*");
        handler.setScript("src/main.py");
        model.addHandler(handler);

        try
        {
            model.save();
        }
        catch (Exception e)
        {
            ZGaeUtil.logError(e);
        }

        try
        {
            createIndexYaml(aProject);
        }
        catch (Exception e)
        {
            ZGaeUtil.logError(e);
        }

        try
        {
            createMainPy(aProject);
        }
        catch (Exception e)
        {
            ZGaeUtil.logError(e);
        }
    }

    /**
     * Creates the index.yaml file.
     *
     * @param aProject
     * @throws CoreException
     * @throws IOException
     */
    protected void createIndexYaml(IProject aProject) throws CoreException, IOException
    {
        createResourceFromTemplate(aProject, "support/new_project_template/index.yaml", "index.yaml", true);
    }

    /**
     * Creates the src/main.py file.
     *
     * @param aProject
     * @throws CoreException
     * @throws IOException
     */
    protected void createMainPy(IProject aProject) throws CoreException, IOException
    {
        createResourceFromTemplate(aProject, "support/new_project_template/main.py", "src/main.py", false);
    }

    /**
     * Creates a resource from a template file in the SDK.
     *
     * @param aProject
     * @param aTemplatePath
     * @throws CoreException
     * @throws IOException
     */
    protected void createResourceFromTemplate(IProject aProject, String aTemplatePath, String aOutputPath,
            boolean aDerived) throws CoreException, IOException
            {
        InputStream iStream = null;
        try
        {
            Bundle bundle = ZGaeSDKActivator.getDefault().getBundle();
            URL url = FileLocator.find(bundle, new Path(aTemplatePath), null);
            iStream = url.openStream();
            IFile file = aProject.getFile(new Path(aOutputPath));
            int flags = IResource.FORCE;
            if (aDerived)
                flags |= IResource.DERIVED;
            file.create(iStream, flags, null);
        }
        finally
        {
            ZGaeCloser.close(iStream);
        }
            }

    /**
     * @return the project
     */
    protected IProject getProject()
    {
        return mProject;
    }

    /**
     * @param aProject the project to set
     */
    protected void setProject(IProject aProject)
    {
        mProject = aProject;
    }
}
